package com.yupi.springbootinit.statemachine.controller;

import com.yupi.springbootinit.common.BaseResponse;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.common.ResultUtils;
import com.yupi.springbootinit.statemachine.core.StateContext;
import com.yupi.springbootinit.statemachine.core.StateTransitionRecord;
import com.yupi.springbootinit.statemachine.core.TransitionResult;
import com.yupi.springbootinit.statemachine.dto.AvailableTransitionsRequest;
import com.yupi.springbootinit.statemachine.dto.StateTransitionHistoryRequest;
import com.yupi.springbootinit.statemachine.dto.StateTransitionRequest;
import com.yupi.springbootinit.statemachine.enums.*;
import com.yupi.springbootinit.statemachine.service.NotificationService;
import com.yupi.springbootinit.statemachine.service.StateMachineService;
import com.yupi.springbootinit.statemachine.service.TaskCenterService;
import com.yupi.springbootinit.statemachine.vo.AvailableTransitionsVO;
import com.yupi.springbootinit.statemachine.vo.NotificationVO;
import com.yupi.springbootinit.statemachine.vo.StateTransitionVO;
import com.yupi.springbootinit.statemachine.vo.TaskVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 状态机管理Controller
 * 提供状态转换操作、查询、待办任务和通知管理等接口
 */
@Slf4j
@RestController
@RequestMapping("/api/statemachine")
public class StateMachineController {
    
    @Resource
    private StateMachineService stateMachineService;
    
    @Resource
    private TaskCenterService taskCenterService;
    
    @Resource
    private NotificationService notificationService;
    
    /**
     * 执行状态转换
     */
    @PostMapping("/transition")
    @Operation(summary = "执行状态转换", description = "执行指定实体的状态转换操作")
    public BaseResponse<StateTransitionVO> executeTransition(@Valid @RequestBody StateTransitionRequest request) {
        try {
            // 构建状态上下文
            StateContext context = buildStateContext(request);
            
            // 执行状态转换
            TransitionResult result = stateMachineService.executeTransition(context);
            
            // 构建返回结果
            StateTransitionVO vo = buildStateTransitionVO(result, request);
            
            if (result.isSuccess()) {
                log.info("状态转换成功: 实体[{}:{}] {} -> {}", 
                        request.getEntityType(), request.getEntityId(),
                        request.getFromState(), request.getToState());
                return ResultUtils.success(vo);
            } else {
                log.warn("状态转换失败: 实体[{}:{}] {} -> {}, 原因: {}", 
                        request.getEntityType(), request.getEntityId(),
                        request.getFromState(), request.getToState(),
                        result.getErrorMessage());
                return ResultUtils.error(ErrorCode.OPERATION_ERROR, result.getErrorMessage());
            }
            
        } catch (Exception e) {
            log.error("状态转换异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "状态转换异常: " + e.getMessage());
        }
    }
    
    /**
     * 查询状态转换历史
     */
    @PostMapping("/history")
    @Operation(summary = "查询状态转换历史", description = "查询指定实体的状态转换历史记录")
    public BaseResponse<List<StateTransitionRecord>> getTransitionHistory(@Valid @RequestBody StateTransitionHistoryRequest request) {
        try {
            List<StateTransitionRecord> history = stateMachineService.getTransitionHistory(
                    request.getEntityType(), 
                    request.getEntityId()
            );
            
            log.debug("查询状态转换历史: 实体[{}:{}], 记录数: {}", 
                    request.getEntityType(), request.getEntityId(), history.size());
            
            return ResultUtils.success(history);
            
        } catch (Exception e) {
            log.error("查询状态转换历史异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询可用的状态转换
     */
    @PostMapping("/available-transitions")
    @Operation(summary = "查询可用状态转换", description = "查询指定状态类型和当前状态的可用转换")
    public BaseResponse<AvailableTransitionsVO> getAvailableTransitions(@Valid @RequestBody AvailableTransitionsRequest request) {
        try {
            List<String> availableStates = stateMachineService.getAvailableTransitions(
                    request.getStateType(), 
                    request.getCurrentState()
            );
            
            AvailableTransitionsVO vo = new AvailableTransitionsVO();
            vo.setStateType(request.getStateType());
            vo.setCurrentState(request.getCurrentState());
            vo.setAvailableStates(availableStates);
            
            log.debug("查询可用状态转换: 状态类型={}, 当前状态={}, 可用转换数: {}", 
                    request.getStateType(), request.getCurrentState(), availableStates.size());
            
            return ResultUtils.success(vo);
            
        } catch (Exception e) {
            log.error("查询可用状态转换异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 检查状态转换是否合法
     */
    @GetMapping("/can-transition")
    @Operation(summary = "检查状态转换合法性", description = "检查指定的状态转换是否合法")
    public BaseResponse<Boolean> canTransition(
            @Parameter(description = "状态类型") @RequestParam String stateType,
            @Parameter(description = "源状态") @RequestParam String fromState,
            @Parameter(description = "目标状态") @RequestParam String toState) {
        try {
            boolean canTransition = stateMachineService.canTransition(stateType, fromState, toState);
            
            log.debug("检查状态转换合法性: {} {} -> {} = {}", 
                    stateType, fromState, toState, canTransition);
            
            return ResultUtils.success(canTransition);
            
        } catch (Exception e) {
            log.error("检查状态转换合法性异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "检查失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询部门待办任务
     */
    @GetMapping("/tasks/department/{department}")
    @Operation(summary = "查询部门待办任务", description = "查询指定部门的待办任务列表")
    public BaseResponse<List<TaskVO>> getDepartmentTasks(
            @Parameter(description = "部门名称") @PathVariable String department,
            @Parameter(description = "任务状态") @RequestParam(required = false) String status) {
        try {
            TaskCenterService.TaskStatus taskStatus = null;
            if (status != null && !status.isEmpty()) {
                taskStatus = TaskCenterService.TaskStatus.valueOf(status.toUpperCase());
            }
            
            List<TaskCenterService.Task> tasks = taskCenterService.getDepartmentTasks(department, taskStatus);
            List<TaskVO> taskVOs = tasks.stream()
                    .map(this::buildTaskVO)
                    .collect(Collectors.toList());
            
            log.debug("查询部门待办任务: 部门={}, 状态={}, 任务数: {}", 
                    department, status, taskVOs.size());
            
            return ResultUtils.success(taskVOs);
            
        } catch (Exception e) {
            log.error("查询部门待办任务异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询用户待办任务
     */
    @GetMapping("/tasks/user/{userId}")
    @Operation(summary = "查询用户待办任务", description = "查询指定用户的待办任务列表")
    public BaseResponse<List<TaskVO>> getUserTasks(
            @Parameter(description = "用户ID") @PathVariable String userId,
            @Parameter(description = "任务状态") @RequestParam(required = false) String status) {
        try {
            TaskCenterService.TaskStatus taskStatus = null;
            if (status != null && !status.isEmpty()) {
                taskStatus = TaskCenterService.TaskStatus.valueOf(status.toUpperCase());
            }
            
            List<TaskCenterService.Task> tasks = taskCenterService.getUserTasks(userId, taskStatus);
            List<TaskVO> taskVOs = tasks.stream()
                    .map(this::buildTaskVO)
                    .collect(Collectors.toList());
            
            log.debug("查询用户待办任务: 用户ID={}, 状态={}, 任务数: {}", 
                    userId, status, taskVOs.size());
            
            return ResultUtils.success(taskVOs);
            
        } catch (Exception e) {
            log.error("查询用户待办任务异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新任务状态
     */
    @PutMapping("/tasks/{taskId}/status")
    @Operation(summary = "更新任务状态", description = "更新指定任务的状态")
    public BaseResponse<Boolean> updateTaskStatus(
            @Parameter(description = "任务ID") @PathVariable Long taskId,
            @Parameter(description = "新状态") @RequestParam String status) {
        try {
            TaskCenterService.TaskStatus taskStatus = TaskCenterService.TaskStatus.valueOf(status.toUpperCase());
            boolean success = taskCenterService.updateTaskStatus(taskId, taskStatus);
            
            log.info("更新任务状态: 任务ID={}, 新状态={}, 结果={}", taskId, status, success);
            
            return ResultUtils.success(success);
            
        } catch (Exception e) {
            log.error("更新任务状态异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "更新失败: " + e.getMessage());
        }
    }
    
    /**
     * 完成任务
     */
    @PutMapping("/tasks/{taskId}/complete")
    @Operation(summary = "完成任务", description = "标记指定任务为已完成")
    public BaseResponse<Boolean> completeTask(
            @Parameter(description = "任务ID") @PathVariable Long taskId,
            @Parameter(description = "完成人") @RequestParam String completedBy) {
        try {
            boolean success = taskCenterService.completeTask(taskId, completedBy);
            
            log.info("完成任务: 任务ID={}, 完成人={}, 结果={}", taskId, completedBy, success);
            
            return ResultUtils.success(success);
            
        } catch (Exception e) {
            log.error("完成任务异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "操作失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询部门通知
     */
    @GetMapping("/notifications/department/{department}")
    @Operation(summary = "查询部门通知", description = "查询指定部门的通知消息")
    public BaseResponse<List<NotificationVO>> getDepartmentNotifications(
            @Parameter(description = "部门名称") @PathVariable String department,
            @Parameter(description = "通知状态") @RequestParam(required = false) String status) {
        try {
            NotificationService.NotificationStatus notificationStatus = null;
            if (status != null && !status.isEmpty()) {
                notificationStatus = NotificationService.NotificationStatus.valueOf(status.toUpperCase());
            }
            
            List<NotificationService.Notification> notifications = notificationService.getDepartmentNotifications(department, notificationStatus);
            List<NotificationVO> notificationVOs = notifications.stream()
                    .map(this::buildNotificationVO)
                    .collect(Collectors.toList());
            
            log.debug("查询部门通知: 部门={}, 状态={}, 通知数: {}", 
                    department, status, notificationVOs.size());
            
            return ResultUtils.success(notificationVOs);
            
        } catch (Exception e) {
            log.error("查询部门通知异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询用户通知
     */
    @GetMapping("/notifications/user/{userId}")
    @Operation(summary = "查询用户通知", description = "查询指定用户的通知消息")
    public BaseResponse<List<NotificationVO>> getUserNotifications(
            @Parameter(description = "用户ID") @PathVariable String userId,
            @Parameter(description = "通知状态") @RequestParam(required = false) String status) {
        try {
            NotificationService.NotificationStatus notificationStatus = null;
            if (status != null && !status.isEmpty()) {
                notificationStatus = NotificationService.NotificationStatus.valueOf(status.toUpperCase());
            }
            
            List<NotificationService.Notification> notifications = notificationService.getUserNotifications(userId, notificationStatus);
            List<NotificationVO> notificationVOs = notifications.stream()
                    .map(this::buildNotificationVO)
                    .collect(Collectors.toList());
            
            log.debug("查询用户通知: 用户ID={}, 状态={}, 通知数: {}", 
                    userId, status, notificationVOs.size());
            
            return ResultUtils.success(notificationVOs);
            
        } catch (Exception e) {
            log.error("查询用户通知异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 标记通知为已读
     */
    @PutMapping("/notifications/{notificationId}/read")
    @Operation(summary = "标记通知已读", description = "标记指定通知为已读状态")
    public BaseResponse<Boolean> markNotificationAsRead(@Parameter(description = "通知ID") @PathVariable Long notificationId) {
        try {
            boolean success = notificationService.markAsRead(notificationId);
            
            log.info("标记通知已读: 通知ID={}, 结果={}", notificationId, success);
            
            return ResultUtils.success(success);
            
        } catch (Exception e) {
            log.error("标记通知已读异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "操作失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取任务统计信息
     */
    @GetMapping("/statistics/tasks/{department}")
    @Operation(summary = "获取任务统计", description = "获取指定部门的任务统计信息")
    public BaseResponse<Map<String, Object>> getTaskStatistics(@Parameter(description = "部门名称") @PathVariable String department) {
        try {
            Map<String, Object> statistics = taskCenterService.getTaskStatistics(department);
            
            log.debug("获取任务统计: 部门={}", department);
            
            return ResultUtils.success(statistics);
            
        } catch (Exception e) {
            log.error("获取任务统计异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取通知统计信息
     */
    @GetMapping("/statistics/notifications/{department}")
    @Operation(summary = "获取通知统计", description = "获取指定部门的通知统计信息")
    public BaseResponse<Map<String, Object>> getNotificationStatistics(@Parameter(description = "部门名称") @PathVariable String department) {
        try {
            Map<String, Object> statistics = notificationService.getNotificationStatistics(department);
            
            log.debug("获取通知统计: 部门={}", department);
            
            return ResultUtils.success(statistics);
            
        } catch (Exception e) {
            log.error("获取通知统计异常", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 构建状态上下文
     */
    private StateContext buildStateContext(StateTransitionRequest request) {
        StateContext context = new StateContext();
        context.setEntityId(request.getEntityId());
        context.setEntityType(request.getEntityType());
        context.setCurrentState(parseState(request.getEntityType(), request.getFromState()));
        context.setTargetState(parseState(request.getEntityType(), request.getToState()));
        context.setEvent(parseEvent(request.getEntityType(), request.getEventCode()));
        context.setOperatorId(request.getOperatorId());
        context.setOperatorName(request.getOperatorName());
        context.setRemark(request.getRemark());
        
        // 设置扩展参数
        if (request.getParameters() != null) {
            request.getParameters().forEach(context::addParameter);
        }
        
        return context;
    }
    
    /**
     * 解析状态枚举
     */
    private com.yupi.springbootinit.statemachine.core.State parseState(String entityType, String stateCode) {
        switch (entityType.toUpperCase()) {
            case "ORDER":
                return OrderStateEnum.valueOf(stateCode);
            case "PROCESS_INSTANCE":
                return ProcessInstanceStateEnum.valueOf(stateCode);
            case "PROCESS_SHEET":
                return ProcessSheetStateEnum.valueOf(stateCode);
            case "PRODUCTION_SCHEDULE":
                return ProductionScheduleStateEnum.valueOf(stateCode);
            case "QUALITY_INSPECTION":
                return QualityInspectionStateEnum.valueOf(stateCode);
            default:
                throw new IllegalArgumentException("不支持的实体类型: " + entityType);
        }
    }
    
    /**
     * 解析事件枚举
     */
    private com.yupi.springbootinit.statemachine.core.Event parseEvent(String entityType, String eventCode) {
        if (eventCode == null || eventCode.isEmpty()) {
            return null;
        }
        
        switch (entityType.toUpperCase()) {
            case "ORDER":
                return OrderEventEnum.valueOf(eventCode);
            case "PROCESS_INSTANCE":
                return ProcessInstanceEventEnum.valueOf(eventCode);
            case "PROCESS_SHEET":
                return ProcessSheetEventEnum.valueOf(eventCode);
            case "PRODUCTION_SCHEDULE":
                return ProductionScheduleEventEnum.valueOf(eventCode);
            case "QUALITY_INSPECTION":
                return QualityInspectionEventEnum.valueOf(eventCode);
            default:
                throw new IllegalArgumentException("不支持的实体类型: " + entityType);
        }
    }
    
    /**
     * 构建状态转换VO
     */
    private StateTransitionVO buildStateTransitionVO(TransitionResult result, StateTransitionRequest request) {
        StateTransitionVO vo = new StateTransitionVO();
        vo.setEntityId(request.getEntityId());
        vo.setEntityType(request.getEntityType());
        vo.setFromState(request.getFromState());
        vo.setToState(request.getToState());
        vo.setSuccess(result.isSuccess());
        vo.setErrorCode(result.getErrorCode());
        vo.setErrorMessage(result.getErrorMessage());
        vo.setDuration(result.getDuration());
        return vo;
    }
    
    /**
     * 构建任务VO
     */
    private TaskVO buildTaskVO(TaskCenterService.Task task) {
        TaskVO vo = new TaskVO();
        vo.setTaskId(task.getTaskId());
        vo.setTaskType(task.getTaskType().name());
        vo.setTaskTypeDesc(task.getTaskType().getDescription());
        vo.setBusinessId(task.getBusinessId().toString());
        vo.setDepartment(task.getDepartment());
        vo.setTitle(task.getTitle());
        vo.setDescription(task.getDescription());
        vo.setStatus(task.getStatus().name());
        vo.setStatusDesc(task.getStatus().getDescription());
        vo.setCreateTime(task.getCreateTime());
        vo.setUpdateTime(task.getUpdateTime());
        vo.setAssignee(task.getAssignee());
        vo.setPriority(task.getPriority());
        return vo;
    }
    
    /**
     * 构建通知VO
     */
    private NotificationVO buildNotificationVO(NotificationService.Notification notification) {
        NotificationVO vo = new NotificationVO();
        vo.setNotificationId(notification.getNotificationId());
        vo.setType(notification.getType().name());
        vo.setTypeDesc(notification.getType().getDescription());
        vo.setTitle(notification.getTitle());
        vo.setContent(notification.getContent());
        vo.setTargetDepartment(notification.getTargetDepartment());
        vo.setTargetUser(notification.getTargetUser());
        vo.setBusinessId(notification.getBusinessId().toString());
        vo.setStatus(notification.getStatus().name());
        vo.setStatusDesc(notification.getStatus().getDescription());
        vo.setCreateTime(notification.getCreateTime());
        vo.setReadTime(notification.getReadTime());
        vo.setPriority(notification.getPriority());
        return vo;
    }
}